import OlMap from 'ol/Map';
import OlProjection from 'ol/proj/Projection';
import {OlLayer, OlLayerGroup, OlProj, OlTileLayer} from '../entity/ol';
import OlView from 'ol/View';
import Control from 'ol/control/Control';
import OlControlScaleLine from 'ol/control/ScaleLine';
import XYZ from 'ol/source/XYZ';
import {DcMapOptions} from '../entity/dc-map-options';
import {SbVectorLayer} from './SbVectorLayer';
import {timer} from 'rxjs';

export class SbMap extends OlMap {
    private _insearch = false;
    private _lastHoverPixel: number[];

    constructor(private sbMapOptions: DcMapOptions) {
        super(Object.assign(sbMapOptions, {
            controls: []
        }));

        this.updateByOptions(sbMapOptions);
    }

    private _useDefaultClick = true;

    get useDefaultClick(): boolean {
        return this._useDefaultClick;
    }

    set useDefaultClick(value: boolean) {
        this._useDefaultClick = value;
    }

    private _yxLayer: OlLayer | OlLayerGroup = this.createYxMap();

    get yxLayer() {
        return this._yxLayer;
    }

    private _dzLayer: OlLayer | OlLayerGroup = this.createDzMap();

    get dzLayer() {
        return this._dzLayer;
    }

    get view() {
        return this.getView();
    }

    get projection() {
        return this.getView().getProjection();
    }

    bindEvent() {
        this.on('pointermove', (mapEvent) => {
            // 下方地图经纬度
            const coordinate = mapEvent.coordinate;
            // var coordinate  = ol.proj.transform(mapEvent.coordinate, "EPSG:3857","EPSG:4326")
            // $(".coor_x").text(coordinate[0]);
            // $(".coor_y").text(coordinate[1]);

            this._lastHoverPixel = [mapEvent.pixel[0], mapEvent.pixel[1]];
            timer(100).subscribe((pixel) => {
                const vv = true;
                // const vv = Math.abs(this._lastHoverPixel[0] - pixel[0]) < 2 &&
                //     Math.abs(this._lastHoverPixel[1] - pixel[1]) < 2;
                if (!this._insearch && vv) {
                    this._insearch = true;

                    let layer = null;
                    let feature = null;
                    // 只获取第一层的数据;
                    const flag = this.forEachFeatureAtPixel(mapEvent.pixel, (feature_, layer_) => {
                        if (layer_ && layer_ instanceof SbVectorLayer) {
                            layer = layer_;
                            feature = feature_;
                            return true;
                        } else {
                            return false;
                        }
                    });
                    // 添加手型
                    if (flag) {
                        this.getTargetElement().style.cursor = 'pointer';
                        // $SbMapCursor.setPoint();
                    } else {
                        this.getTargetElement().style.cursor = 'auto';
                        // $SbMapCursor.setPan(map.getTargetElement());
                    }
                    // if (flag) {
                    //     if (layer && layer._pointermoveCallback) {
                    //         layer._pointermoveCallback(feature, layer, coordinate);
                    //     }
                    // } else {
                    //     if (lastFlag && (defaultProjectId == "p_pipeline" || defaultProjectId == "p_yjzh")) {
                    //         if (lastLayer && lastLayer._pointermoveOutCallback) {
                    //             lastLayer._pointermoveOutCallback(lastLayer);
                    //         }
                    //     }
                    // }
                    // lastLayer = layer;
                    // lastFlag = flag;

                    this._insearch = false;
                }
            });

        });

        // 添加点击事件
        this.on('singleclick', mapEvent => {
            if (this.useDefaultClick) {
                let layer = null;
                let feature = null;
                // 只获取第一层的数据;
                const flag = this.forEachFeatureAtPixel(mapEvent.pixel, (feature_, layer_) => {
                    if (layer_ && layer_ instanceof SbVectorLayer) {
                        layer = layer_;
                        feature = feature_;
                        return true;
                    } else {
                        return false;
                    }
                });
                if (!flag) {
                    // flag = map.forEachLayerAtPixel(mapEvent.pixel, function(layer_) {
                    //     layer = layer_;
                    //     return true;
                    // },this,function(layer){
                    //     if(layer._sbData){
                    //         var data = layer._sbData;
                    //         if(data.layerType == '1' && (data.tileType == 'ASR')){
                    //             return true;
                    //         }else{
                    //             return false;
                    //         }
                    //     }else{
                    //         return false;
                    //     }
                    // },this);
                }
                if (flag && layer && layer instanceof SbVectorLayer) {
                    layer.featureClickCallback(feature, layer, mapEvent);
                }
            }
        });
    }

    /**
     * 显示电子地图
     */
    showDzMap() {
        this.yxLayer.setVisible(false);
        this.dzLayer.setVisible(true);
    }

    /**
     * 显示影像地图
     */
    showYxMap() {
        this.yxLayer.setVisible(true);
        this.dzLayer.setVisible(false);
    }

    /**
     * 获取电子地图图层组
     */
    createDzMap(): OlLayer | OlLayerGroup {
        const dzLayer = new OlTileLayer({
            source: new XYZ({
                url: `http://t{0-7}.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${this.sbMapOptions.tk}`,
                crossOrigin: 'anonymous',
            }),
            // name: '电子地图'
        });
        const dzZjLayer = new OlTileLayer({
            source: new XYZ({
                url: `http://t{0-7}.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=${this.sbMapOptions.tk}`,
                crossOrigin: 'anonymous',
            }),
            // name: '电子地图注记'
        });

        const layerGroup = new OlLayerGroup({
            layers: [dzLayer, dzZjLayer]
        });

        layerGroup.set('name', '电子地图');
        return layerGroup;
    }

    /**
     * 获取影像地图图层组
     */
    createYxMap(): OlLayer | OlLayerGroup {
        const yxLayer = new OlTileLayer({
            source: new XYZ({
                url: `http://t{0-7}.tianditu.com/DataServer?T=img_w&?x={x}&y={y}&l={z}&tk=${this.sbMapOptions.tk}`,
                crossOrigin: 'anonymous',
            }),
            // name: '卫星影像'
        });

        const yxZjLayer = new OlTileLayer({
            source: new XYZ({
                url: `http://t{0-7}.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=${this.sbMapOptions.tk}`,
                crossOrigin: 'anonymous',
            }),
            // name: '卫星影像注记'
        });

        const layerGroup = new OlLayerGroup({
            layers: [yxLayer, yxZjLayer],
            visible: false,
        });
        layerGroup.set('name', '卫星影像');
        return layerGroup;
    }

    private updateByOptions(sbMapOptions: DcMapOptions) {
        const projectionOption = sbMapOptions.projectionOption;

        let projection: OlProjection;
        // 初始化 projection
        if (typeof projectionOption === 'string') {
            projection = OlProj.get(projectionOption);
        } else {
            projection = new OlProjection(projectionOption);
        }
        // 如果view为空，使用projection
        const viewOption = Object.assign({}, sbMapOptions.viewOption);
        if (!viewOption.projection) {
            viewOption.projection = projection;
        }
        // // 初始化 view
        const view = new OlView(viewOption);
        this.setView(view);

        // 添加图层
        this.addLayer(this.dzLayer);
        this.addLayer(this.yxLayer);

        // 添加控制层
        const controls = this.getMapControl();
        for (const control of controls) {
            this.addControl(control);
        }

        this.bindEvent();
    }

    private getMapControl(): Control[] {
        const controls = [];

        if (this.sbMapOptions.controlOption.scaleLineControl) {
            controls.push(////  比例尺栏
                new OlControlScaleLine({
                    units: 'metric'
                }));
        }
        // ‘+’、‘-’按钮
        // controls.push(new OlControlZoom({zoomInLabel: '-', zoomOutLabel: '+'}));

        return controls;
    }

}
